﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.Security.AccessControl;
using System.Security.Permissions;
using OptionsForm;
using System.Runtime.Serialization.Formatters.Soap;

namespace HighScores
{
    [Serializable]
    public class Score
    {
        protected bool Equals(Score other)
        {
            return string.Equals(Name, other.Name) && Time == other.Time && Level.Equals(other.Level);
        }

        public Score(string name, Level level, int time)
        {
            Name = name;
            Level = level;
            Time = time;
        }

        public Score()
        {
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = (Name != null ? Name.GetHashCode() : 0);
                hashCode = (hashCode*397) ^ Time;
                hashCode = (hashCode*397) ^ Level.GetHashCode();
                return hashCode;
            }
        }

        public string Name { get; set; }

        public int Time { get; set; }
        public Level Level { get; set; }


        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            return obj.GetType() == this.GetType() && Equals((Score) obj);
        }

        private readonly string path = @"..\Scores.txt";

        public void ScoresWriter(FileMode fileMode = FileMode.Append)
        {
            using (var writer = new FileStream(path, fileMode))
            {
                var bf = new SoapFormatter();
                bf.Serialize(writer, this);
            }
        }
    }

    public class ScoreKeeper : BindingList<Score>
    {
        private readonly string path = @"..\Scores.txt";

        public ScoreKeeper()
        {
            ScoresReader();
        }

        public void ScoresWriter(FileMode mode = FileMode.Append)
        {
            using (var writer = new FileStream(path, mode))
            {
                var bf = new SoapFormatter();
                foreach (var score in this)
                {
                    bf.Serialize(writer, score);
                }
            }
        }

        private void ScoresReader()
        {
            if (!File.Exists(path))
                return;

            using (var serializationStream = new FileStream(path, FileMode.Open))
            {
                var bf = new SoapFormatter();
                while (serializationStream.Position < serializationStream.Length)
                {
                    this.Add((Score) bf.Deserialize(serializationStream));
                }
            }
        }
    }
}